package ge.modules.logics;


import ge.engine.Actor;
import ge.engine.Engine;
import ge.engine.Positionable;
import ge.engine.PositionableArea;
import ge.lowlevel.CollisionEngine;
import ge.modules.Module;
import ge.modules.events.CollisionListener;


/**
 * 	
 * @author Abel
 *	Abstract class who define the basics features of a geometric figure
 *	Has the Module's behavior, and can be tested with the Collision Engine
 */
public abstract class GeomCollideFigure implements Module, PositionableArea
{
	private int id;
	private boolean fixed;
	protected double X = 0;
	protected double Y = 0;
	protected boolean draw = false;
	protected CollisionListener colision = new CollisionListener(this);
	protected Positionable attachTo = null;
	private Actor isOwned;
	
	/**
	 * 	
	 * @return The actor who owns that geometric figure
	 */
	public Actor getOwner()
	{
		return isOwned;
	}
	/**
	 * Sets the actor who owns that geometric figure
	 * @param a Actor
	 */
	public void setOwner(Actor a)
	{
		isOwned = a;
	}
	
	
	/**
	 *  New geometric figure identify by id
	 * @param id
	 */
	public GeomCollideFigure(int id)
	{
		this.id = id;
		fixed = false;
		isOwned = null;
	}
	/**
	 * New geometric with default identify 0.
	 */
	public GeomCollideFigure()
	{
		this.id = 0;
		fixed = false;
	}
	
	public int getId()
	{
		return id;
	}
	/**
	 * 	
	 * @return Fixed value (true if it's fixed in the camera)
	 */
	public boolean isFixed() 
	{
		return fixed;
	}
	/**
	 * 	Fixed to the camera
	 * @param fixed Boolean Attribute
	 */
	public void setFixed(boolean fixed)
	{
		this.fixed = fixed;
	}
	/**
	 * 	Thats a such importan function. Your GeomCollide may be associated to a other element
	 * 	and you'll usually want that other element moves when the geometric figure is moved.
	 *  (For example, if you are using a SolidModule, and your character collides whit it,
	 *  the geometric figure won't overlap it, but, your sprite modulo won't too.
	 *   
	 *  If you associates a Positionable element, it will be moved always the geometric figure
	 *  moves.
	 * @param positionable Element to positioned in the SetPos geometric figure function.
	 * 			If its null, anything will be moved.
	 */
	public void attachedTo(Positionable positionable)
	{
		this.attachTo = positionable;
	}
	public void setPos(double x, double y) {
		
		//That conditions avoids a stack overflow exception
		if(x != X || y != Y)
		{
			X = x;
			Y = y;
			
			if(attachTo != null && (attachTo.getX() != X || attachTo.getY() != Y))
				attachTo.setPos(x, y);
		}
	}
	public double getX() 
	{
		if(!fixed)
			return X;
		
		return Engine.getCamera().getX()+X; //If it's fixed the absolute follows the camera
	}
	public double getY() {
		if(!fixed)
			return Y;
		
		return Engine.getCamera().getY()+Y; //If it's fixed the absolute follows the camera
	}
	
	/**
	 * 	Sets the draw property. 
	 * @param draw If it's true the figure will be drawn in the canvas.
	 */
	public void setDraw(boolean draw)
	{
		this.draw = draw;
	}
	/**
	 * 	Attach the figure to the collide engine, then all the figures could be tested against it in 
	 * 	the collision test.
	 * @param enable 	True attach, false remove out the engine.
	 */
	public void enableCollide(boolean enable)
	{
		if(enable)
			CollisionEngine.get().attachFigure(this);
		else
			CollisionEngine.get().removeFigure(this);
	}
	/**
	 * 
	 * @return true if the figure is now enable in the logic  collision engine
	 */
	public boolean isEnable()
	{
		return CollisionEngine.get().isAttached(this);
	}
	
	@Override
	public void draw() 
	{
	}
	@Override
	public void update() 
	{
		colision.update();
		
	}
	
	@Override
	public void delete()
	{
		enableCollide(false);
	}
}
